package com.zrq.secondkill.service;



import org.springframework.lang.Nullable;

import java.util.UUID;

/**
 * 会过期,可能宕机丢失的存储,用于保存用户的会话信息
 *
 * @author zrq
 */
public interface SessionService {

    /**
     * 向用户会话的属性中添加键值对
     * 使用默认过期时间1小时,需要设置过期时间可使用{@link SessionService#setAttribute(String, String, Object, Integer)}
     *
     * @param token 用户身份标识,可以自己选择 {@link SessionService}也提供token生成功能
     * @param key   存储的键
     * @param value 存储的值,调用者无需显示序列化
     */
    default void setAttribute(String token, String key, Object value) {
        setAttribute(token, key, value, 3600);
    }

    /**
     * 向用户会话的属性中添加键值对
     *
     * @param token  用户身份标识,可以自己选择 {@link SessionService}也提供token生成功能
     * @param key    存储的键
     * @param value  存储的值,调用者无需显示序列化
     * @param expire 过期时间,单位为秒,会覆盖之前的设置,为null时保留上次设置不覆盖
     */
    void setAttribute(String token, String key, Object value, @Nullable Integer expire);

    /**
     * 获取用户会话的属性的值
     * 默认将过期时间重置为一小时,需要设置过期时间可使用{@link SessionService#getAttribute(String, String, Integer)}
     *
     * @param token 用户身份标识
     * @param key   存储的键
     * @return 键对应的值或null, 调用者应当强转成正确的类型使用
     */
    default Object getAttribute(String token, String key) {
        return getAttribute(token, key, 3600);
    }

    /**
     * 获取用户会话的属性的值
     *
     * @param token  用户身份标识
     * @param key    存储的键
     * @param expire 过期时间,单位为秒,会覆盖之前的设置,为null时保留上次设置不覆盖
     * @return 键对应的值或null, 调用者应当强转成正确的类型使用
     */
    Object getAttribute(String token, String key, @Nullable Integer expire);

    /**
     * 生成全局唯一token
     * TODO(zrq): 改为使用UniqueIdService
     *
     * @return 唯一token
     */
    default String generateUniqueToken() {
        String uuidToken = UUID.randomUUID().toString();
        return uuidToken.replace("-", "");
    }

}
